package com.yanfan.dlt698_45.frame;


import com.yanfan.dlt698_45.code.DestinationCode;
import com.yanfan.dlt698_45.code.FunctionCode;
import com.yanfan.dlt698_45.exception.DLT698_45TransportException;
import io.netty.buffer.ByteBuf;

/**
 * @author oliver foo
 * @description
 * @date 2023/3/21 14:56
 */
abstract public class SecurityResponse extends DLT698_45Frame {
    private byte clientAddress;
    private boolean exception = false;

    private byte error = 0x00;

    public SecurityResponse(byte[] address, byte addressType) throws DLT698_45TransportException {
        super(address, addressType);
    }

    public static SecurityResponse createSecurityResponse(ByteBuf buf) throws DLT698_45TransportException {
        // 两个byte 的长度
        int length = buf.readUnsignedShort();
        // 控制位
        byte control = buf.readByte();
        // 地址特征值
        byte addressDesc = buf.readByte();
        // 取后四位地址长度
        ///取值范围：0…15，对应表示1…16个字节长度
        int addressLength = (addressDesc & 0xf) + 1;
        byte[] address = new byte[addressLength];
        // 读出地址
        buf.readBytes(address);
        // 客户端地址
        buf.readByte();
        // 两个byte的头校验
        short sc = buf.readShort();

        SecurityResponse response = new SecurityGetNormalResponse(address);

        // FrameType.SECURITY_RESPONSE
        byte frameType = buf.readByte();
        // 0 明文 1 密文    2 错误
        byte info = buf.readByte();
        if (info == 0x02) {
            response.setException(true);
        }
        // 读取明文
        response.read(buf);
        return response;
    }

    protected void read(ByteBuf buf) {
        if (isException()) {
            this.setError(buf.readByte());
        } else {
            readResponse(buf);
        }
    }

    public abstract Object getData();

    protected abstract void readResponse(ByteBuf buf);

    public boolean isException() {
        return exception;
    }

    public void setException(boolean exception) {
        this.exception = exception;
    }

    public byte getError() {
        return error;
    }

    public void setError(byte error) {
        this.error = error;
    }

    @Override
    public boolean hasFollowFrame() {
        return false;
    }

    @Override
    public byte getDestination() {
        return DestinationCode.SERVER_RESPONSE;
    }

    @Override
    public byte getFunctionCode() {
        return FunctionCode.USER_DATA;
    }

    @Override
    public byte getClientAddress() {
        return 0;
    }
}
